package com.swingson.properties;

import com.swingson.exceptions.SwingsonException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author sad
 */
public class PropertiesProcessorResolver {

    //Property processor that attached to property in specific class
    //for example only for "mouseClick" in JComponent" class
    private final Map<String, BasePropertyProcessor> nameClassPropertyProcessors = new HashMap<>();
    //Property processor that just attached to convert json value to specific type
    private final Map<Class, BasePropertyProcessor> typeProcessingPropertyProcessors = new HashMap<>();
    //private final Set<String> propertiesList = new HashSet<String>();//contains all registered properties names. Just for search

    /**
     if you will not provide propertyClasses, it will meant - "for all"<br/>
     propertyClasses - type of receiver field
     **/
    public PropertiesProcessorResolver addTypeProcessingProperty(BasePropertyProcessor processor, Class... types) {
        if (processor == null) {
            throw new SwingsonException("Cannot add null property processor");
        }
        if (types.length == 0) {
            throw new SwingsonException("You should provide class for processor");
        } else {
            for (Class pc : types) {
                if (typeProcessingPropertyProcessors.containsKey(pc)) {
                    System.out.println("Property processor " + typeProcessingPropertyProcessors.get(pc) + " for class [" + pc + "] already registered, but you want to add " + processor);
                }
                typeProcessingPropertyProcessors.put(pc, processor);
            }
        }

        return this;
    }

    /* public boolean isItProperty(String label) {
     return propertiesList.contains(label);
     }*/
    public BasePropertyProcessor getTypeProcessingPropertyProcessor(Class clazz) {
        return typeProcessingPropertyProcessors.get(clazz);
    }

    public void addNameClassPropertyProcessor(String label, Class clazz, BasePropertyProcessor processor) {
        String newLabel = label + "_" + clazz.getSimpleName();
        if (nameClassPropertyProcessors.containsKey(newLabel)) {
            System.out.println("Property processor " + nameClassPropertyProcessors.get(newLabel) + " for label '"+label+"' for class "+clazz.getSimpleName()+", but you want to add new " + processor);
        }
        nameClassPropertyProcessors.put(newLabel, processor);
    }

    public BasePropertyProcessor getNameClassProperty(String label, Class clazz) {
        //try to find processor for clazz or all it subclasses
        while (clazz != null) {
            String newLabel = label + "_" + clazz.getSimpleName();
            if (nameClassPropertyProcessors.containsKey(newLabel)) {
                return nameClassPropertyProcessors.get(newLabel);
            }

            clazz = clazz.getSuperclass();
        }

        return null;
    }
}
